/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 
 * [VW] The original file was taken from the Notepad sample app in the Android SDK 
 */

package com.googlecode.eightqueenshaggle;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

/**
 * Provides access to a database of notes. Each note has a title, the note
 * itself, a creation date and a modified data.
 * 
 * 
 * [VW] At first I will only store solutions to the classical 8 queens problem.
 * It will not be the most general approach, but we'll figure out how dbs work
 * in Android.
 */
public abstract class EQDatabaseContentProvider extends ContentProvider {

	//this string is used to give the Content Provider a unique URI
	public static final String AUTHORITY = "com.googlecode.eightqueenshaggle";
   
    //The content:// style URL for this table  
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/solutionsClassical");
	
    //The default sort order for this table
    public static final String DEFAULT_SORT_ORDER = "modified DESC";
    
	private static final String TAG = "DatabaseHelper";

	private static final String DATABASE_NAME = "eight_queens.db";
	private static final int DATABASE_VERSION = 2;
	private static final String TABLE_NAME = "solutionsClassical";

	// private static HashMap<String, String> sNotesProjectionMap;
	// private static HashMap<String, String> sLiveFolderProjectionMap;

	private static final int MAIN_TABLE = 1;
	// private static final int NOTE_ID = 2;
	// private static final int LIVE_FOLDER_NOTES = 3;

	private static final UriMatcher sUriMatcher;

	/**
	 * This class helps open, create, and upgrade the database file.
	 */
	private static class DatabaseHelper extends SQLiteOpenHelper {

		DatabaseHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
		}

		@Override
		public void onCreate(SQLiteDatabase db) {

			/*
			 * db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " (" + Notes._ID
			 * + " INTEGER PRIMARY KEY," + Notes.TITLE + " TEXT," + Notes.NOTE +
			 * " TEXT," + Notes.CREATED_DATE + " INTEGER," + Notes.MODIFIED_DATE
			 * + " INTEGER" + ");");
			 */

			db.execSQL("CREATE TABLE " + TABLE_NAME + " ("
					+ "solnr INTEGER PRIMARY KEY," + "loc1x INTEGER, "
					+ "loc1y INTEGER, " + "loc2x INTEGER, " + "loc2y INTEGER, "
					+ "loc3x INTEGER, " + "loc3y INTEGER, " + "loc4x INTEGER, "
					+ "loc4y INTEGER, " + "loc5x INTEGER, " + "loc5y INTEGER, "
					+ "loc6x INTEGER, " + "loc6y INTEGER, " + "loc7x INTEGER, "
					+ "loc7y INTEGER, " + "loc8x INTEGER, " + "loc8y INTEGER, "
					+ " );");
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			/*Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
					+ newVersion + ", which will destroy all old data");*/
			
			db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
			
			onCreate(db);
		}
	}

	private DatabaseHelper mOpenHelper;

	/*
	@Override
	public boolean onCreate() {
		mOpenHelper = new DatabaseHelper(getContext());
		return true;
	}*/

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		
		SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
		
		qb.setTables(TABLE_NAME);


		//[VW] we only have one table at first, there I guess we do not need this switch part
		//[VW] hopefully we also won't need a projection part
		
		
		/*switch (sUriMatcher.match(uri)) {
		case NOTES:
			qb.setProjectionMap(sNotesProjectionMap);
			break;

		case NOTE_ID:
			qb.setProjectionMap(sNotesProjectionMap);
			qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));
			break;

		case LIVE_FOLDER_NOTES:
			qb.setProjectionMap(sLiveFolderProjectionMap);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}*/
		
		
		// If no sort order is specified use the default
		String orderBy;
		if (TextUtils.isEmpty(sortOrder)) {
			orderBy = DEFAULT_SORT_ORDER;
		} else {
			orderBy = sortOrder;
		}

		// Get the database and run the query
		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
		
		Cursor c = qb.query(db, projection, selection, selectionArgs, null,
				null, orderBy);

		// Tell the cursor what uri to watch, so it knows when its source data
		// changes
		c.setNotificationUri(getContext().getContentResolver(), uri);
		return c;
	}

	/*
	@Override
	public String getType(Uri uri) {
		switch (sUriMatcher.match(uri)) {
		case NOTES:
		case LIVE_FOLDER_NOTES:
			return Notes.CONTENT_TYPE;

		case NOTE_ID:
			return Notes.CONTENT_ITEM_TYPE;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
	}*/

	@Override
	public Uri insert(Uri uri, ContentValues initialValues) {
		
		// Validate the requested uri
		if (sUriMatcher.match(uri) != MAIN_TABLE) {
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		ContentValues values;
		if (initialValues != null) {
			values = new ContentValues(initialValues);
		} else {
			values = new ContentValues();
		}

		//Long now = Long.valueOf(System.currentTimeMillis());

		// Make sure that the fields are all set
		
		/*if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) {
			values.put(NotePad.Notes.CREATED_DATE, now);
		}

		if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {
			values.put(NotePad.Notes.MODIFIED_DATE, now);
		}

		if (values.containsKey(NotePad.Notes.TITLE) == false) {
			Resources r = Resources.getSystem();
			values.put(NotePad.Notes.TITLE, r
					.getString(android.R.string.untitled));
		}

		if (values.containsKey(NotePad.Notes.NOTE) == false) {
			values.put(NotePad.Notes.NOTE, "");
		}*/
		
		/*[VW] the keys of the db fields are their variable names as strings*/
		
		if(
				values.containsKey("loc1x") == false || 
				values.containsKey("loc1y") == false ||
				
				values.containsKey("loc2x") == false || 
				values.containsKey("loc2y") == false ||
				
				values.containsKey("loc3x") == false || 
				values.containsKey("loc3y") == false ||
				
				values.containsKey("loc4x") == false || 
				values.containsKey("loc4y") == false ||
				
				values.containsKey("loc5x") == false || 
				values.containsKey("loc5y") == false ||
				
				values.containsKey("loc6x") == false || 
				values.containsKey("loc6y") == false ||
				
				values.containsKey("loc7x") == false || 
				values.containsKey("loc7y") == false ||
				
				values.containsKey("loc8x") == false || 
				values.containsKey("loc8y") == false )
		
		{
			
			//We cannot proceed, because we have got faulty data
			throw new SQLException("Failed to insert row into " + uri);
			
		}

		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		
		long rowId = db.insert(TABLE_NAME, " ", values);
		
		if (rowId > 0) {
			Uri noteUri = ContentUris.withAppendedId(CONTENT_URI,
					rowId);
			getContext().getContentResolver().notifyChange(noteUri, null);
			return noteUri;
		}

		throw new SQLException("Failed to insert row into " + uri);
	}

	/*
	@Override
	public int delete(Uri uri, String where, String[] whereArgs) {
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		int count;
		switch (sUriMatcher.match(uri)) {
		case NOTES:
			count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
			break;

		case NOTE_ID:
			String noteId = uri.getPathSegments().get(1);
			count = db.delete(NOTES_TABLE_NAME,
					Notes._ID
							+ "="
							+ noteId
							+ (!TextUtils.isEmpty(where) ? " AND (" + where
									+ ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}*/


	//[VW] We don't need this function, because we only query and insert solutions
	//Unfortunately the interface requires it.
	@Override
	public int update(Uri uri, ContentValues values, String where,
			String[] whereArgs) {
		SQLiteDatabase db = mOpenHelper.getWritableDatabase();
		
		
		int count = 0;
		
		/*switch (sUriMatcher.match(uri)) {
		case NOTES:
			count = db.update(TABLE_NAME, values, where, whereArgs);
			break;

		case NOTE_ID:
			String noteId = uri.getPathSegments().get(1);
			count = db.update(TABLE_NAME, values,
					Notes._ID
							+ "="
							+ noteId
							+ (!TextUtils.isEmpty(where) ? " AND (" + where
									+ ')' : ""), whereArgs);
			break;

		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}*/

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
		
	}

	
		//[VW] This is more simplistic in our case, at least in the simple implementation
		/*
		static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
		sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
		sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes",
				LIVE_FOLDER_NOTES);

		sNotesProjectionMap = new HashMap<String, String>();
		sNotesProjectionMap.put(Notes._ID, Notes._ID);
		sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);
		sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);
		sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE);
		sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE);

		// Support for Live Folders.
		sLiveFolderProjectionMap = new HashMap<String, String>();
		sLiveFolderProjectionMap.put(LiveFolders._ID, Notes._ID + " AS "
				+ LiveFolders._ID);
		sLiveFolderProjectionMap.put(LiveFolders.NAME, Notes.TITLE + " AS "
				+ LiveFolders.NAME);
		// Add more columns here for more robust Live Folders.
	}*/
	
	static {
		sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		sUriMatcher.addURI(AUTHORITY, "MAIN_TABLE", MAIN_TABLE);
	}
}
